package com.s7.app.mvp;

import android.content.Context;
import android.os.Bundle;

import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 抽象类 统一管理View层绑定和解除绑定
 * @param <V>
 */
public abstract class BasePresenter<M extends BaseModel, V extends BaseView> {

    private WeakReference<V> weakView;
    protected V proxyView;
    protected M mModel;
    protected Bundle bundle;
    protected Context context;

    public V getView() {
        return proxyView;
    }

    /**
     * 用于检查View是否为空对象
     *
     * @return
     */
    public boolean isAttachView() {
        return this.weakView != null && this.weakView.get() != null;
    }

    /**
     * 绑定视图
     * @param view
     */
    public void attachView(V view) {
        this.weakView = new WeakReference<>(view);
        MvpViewInvocationHandler invocationHandler = new MvpViewInvocationHandler(this.weakView.get());
        // 在这里采用动态代理
        proxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(),
                view.getClass().getInterfaces(), invocationHandler);
        Proxy.getProxyClass(view.getClass().getClassLoader(), view.getClass().getInterfaces());
        onStart();
    }

    /**
     * 绑定视图
     * @param view
     * @param bundle Bundle 参数
     */
    public void attachView(V view, Bundle bundle) {
        this.bundle = bundle;
        attachView(view);
    }

    /**
     * 绑定视图
     * @param view
     * @param context 上下文对象
     */
    public void attachView(V view, Context context) {
        this.context = context;
        attachView(view);
    }

    /**
     * 绑定视图
     * @param view
     * @param context 上下文对象
     * @param bundle Bundle 参数
     */
    public void attachView(V view, Context context, Bundle bundle) {
        this.context = context;
        this.bundle = bundle;
        attachView(view);
    }

    /**
     * 开始调用
     */
    protected void onStart() {

    }

    /**
     * 销毁调用
     */
    protected void onDestroy() {

    }

    /**
     * 解除绑定（每个V记得使用完之后解绑，主要是用于防止内存泄漏问题）
     */
    public void dettachView() {
        if (this.weakView != null) {
            this.weakView.clear();
        }
        this.weakView = null;
        if (mModel != null) {
            mModel = null;
        }
        onDestroy();
    }

    public class MvpViewInvocationHandler implements InvocationHandler {
        private BaseView mvpView;

        public MvpViewInvocationHandler(BaseView mvpView) {
            this.mvpView = mvpView;
        }

        @Override
        public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable {
            if (isAttachView()) {
                return method.invoke(mvpView, arg2);
            }
            return null;
        }
    }
}
